package cn.csm.jwtlogin.jwt;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.annotation.Order;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;

/**
 * description: TokenFilter <br>
 * date: 2020/10/30 11:21 <br>
 * author: shimi <br>
 * version: 1.0 <br>
 */
@Order(1)
@WebFilter(filterName = "jwtFilter", urlPatterns = {"/*"})
public class JwtFilter implements Filter {

    private final String[] accessUrls = new String[]{
            "/auth/login",
            "/auth/token",
            "/auth/refresh",
            "/swagger-ui.html",
            "/**/swagger-ui/**",
            "/v3/api-docs/**"
    };

    private final JwtProvider jwtProvider;
    private final ObjectMapper objectMapper;

    public JwtFilter(JwtProvider jwtProvider, ObjectMapper objectMapper) {
        this.jwtProvider = jwtProvider;
        this.objectMapper = objectMapper;
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        System.out.println(">>>> requestUrl: " + request.getRequestURI() + ", requestData: "+ objectMapper.writeValueAsString(request.getParameterMap()));
        String requestURI = request.getRequestURI();
        AntPathMatcher matcher = new AntPathMatcher();
        boolean matches = Arrays.stream(accessUrls).anyMatch((url) -> matcher.match(url,requestURI));
        if (matches) {
            filterChain.doFilter(request, response);
        } else {
            //检查token
            String token = jwtProvider.getToken(request);
            if (StringUtils.hasText(token) && jwtProvider.validateToken(token)) {
                filterChain.doFilter(request, response);
            } else {
                response.setContentType("application/json;charset=UTF-8");
                response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "暂未登录或token已过期");
            }
        }
    }

    @Override
    public void destroy() {
    }

}
